/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cn.edu.ldu.views;


import cn.edu.ldu.util.Consts;
import cn.edu.ldu.util.ReceiveMessage;
import cn.edu.ldu.util.Util;
import cn.edu.ldu.views.modules.oss.ReceiveFile;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.io.IOException;
import java.net.*;
import java.util.Date;
import java.util.Enumeration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 *
 * @author Administrator
 */
public class ServerView extends JFrame {

    private Socket clientSocket = null;
    private ServerSocket serverSocket;
    public static int clientNumber = 0;

    /**
     * Creates new form EchoServerFrame
     */
    public ServerView() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jp_top = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jtfPort = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jtfIpaddress = new javax.swing.JTextField();
        jbStart = new javax.swing.JButton();
        jp_bottom = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jtaMessage = new javax.swing.JTextArea();
        jTextArea2 = new javax.swing.JTextArea();
        jScrollPane5 = new javax.swing.JScrollPane();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        jTable1 = new javax.swing.JTable();


        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        jp_top.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "服务器启动面板", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("宋体", 1, 18))); // NOI18N

        jLabel1.setFont(new java.awt.Font("宋体", 0, 18)); // NOI18N
        jLabel1.setText("服务器主机名");

        jtfPort.setFont(new java.awt.Font("宋体", 0, 18)); // NOI18N
        jtfPort.setText("7777");

        jLabel2.setFont(new java.awt.Font("宋体", 0, 18)); // NOI18N
        jLabel2.setText("端口号");

        jtfIpaddress.setFont(new java.awt.Font("宋体", 0, 18)); // NOI18N
        jtfIpaddress.setText("localhost");

        jbStart.setText("启动服务器");
        jbStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbStartActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jp_topLayout = new javax.swing.GroupLayout(jp_top);
        jp_top.setLayout(jp_topLayout);
        jp_topLayout.setHorizontalGroup(
                jp_topLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(jp_topLayout.createSequentialGroup()
                                .addGap(19, 19, 19)
                                .addComponent(jLabel1)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(jtfIpaddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(45, 45, 45)
                                .addComponent(jLabel2)
                                .addGap(18, 18, 18)
                                .addComponent(jtfPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 138, Short.MAX_VALUE)
                                .addComponent(jbStart)
                                .addGap(26, 26, 26))
        );
        jp_topLayout.setVerticalGroup(
                jp_topLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jp_topLayout.createSequentialGroup()
                                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addGroup(jp_topLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                        .addComponent(jLabel1)
                                        .addComponent(jtfIpaddress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(jLabel2)
                                        .addComponent(jtfPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(jbStart))
                                .addGap(19, 19, 19))
        );

        getContentPane().add(jp_top, java.awt.BorderLayout.PAGE_START);

        jp_bottom.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "服务器收到的客户机消息面板", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("宋体", 1, 18))); // NOI18N
        jp_bottom.setLayout(new javax.swing.BoxLayout(jp_bottom, javax.swing.BoxLayout.LINE_AXIS));

        jScrollPane1.setMinimumSize(new java.awt.Dimension(4, 23));
        jScrollPane1.setName(""); // NOI18N

        jtaMessage.setColumns(20);
        jtaMessage.setRows(5);
        jtaMessage.setEnabled(false);
        jScrollPane1.setViewportView(jtaMessage);

        jTextArea2.setBorder(javax.swing.BorderFactory.createTitledBorder("在线列表"));
        jTextArea2.setEnabled(false);
        jScrollPane5.setViewportView(jTextArea2);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 454, Short.MAX_VALUE)
                                .addGap(18, 18, 18)
                                .addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 168, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        jPanel1Layout.setVerticalGroup(
                jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 246, Short.MAX_VALUE)
                        .addComponent(jScrollPane5)
        );

        jp_bottom.add(jPanel1);

        getContentPane().add(jp_bottom, java.awt.BorderLayout.CENTER);

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "用户信息", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("宋体", 1, 18))); // NOI18N
        tableModel = new javax.swing.table.DefaultTableModel(
                new Object [][] {

                },
                new String [] {
                        "NO", "ID", "当前IP", "最近一次IP"
                }
        ){
            boolean[] canEdit = new boolean [] {
                    false, false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        };
        jTable1.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        jTable1.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        jTable1.getTableHeader().setReorderingAllowed(false);
        jTable1.setModel(tableModel);
        for(int i = 0; i < jTable1.getColumnModel().getColumnCount(); i++){
            jTable1.getColumnModel().getColumn(i).setMinWidth(100);
        }
        jTable1.setDoubleBuffered(true);
        jTable1.setRowHeight(24);
        jScrollPane4.setViewportView(jTable1);
        jTable1.getAccessibleContext().setAccessibleName("");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGap(0, 640, Short.MAX_VALUE)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(jPanel2Layout.createSequentialGroup()
                                        .addContainerGap()
                                        .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
                                        .addContainerGap()))
        );
        jPanel2Layout.setVerticalGroup(
                jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGap(0, 152, Short.MAX_VALUE)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 132, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
        );

        getContentPane().add(jPanel2, java.awt.BorderLayout.SOUTH);

        pack();
    }// </editor-fold>

    private void jbStartActionPerformed(java.awt.event.ActionEvent evt) {
        try {
            //创建并启动UDP消息接收线程
            Thread recvThread = new ReceiveMessage(ServerView.this);
            recvThread.start();
            jtaMessage.append("服务器开始侦听...\n");
            //创建并启动文件接收线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        SocketAddress socketAddress = new InetSocketAddress(InetAddress.getLocalHost(), Consts.port);
                        //创建监听套接字
                        ServerSocket listenerSocket = new ServerSocket();
                        //绑定到工作地址
                        listenerSocket.bind(socketAddress);
                        //创建线程
                        int processors = Runtime.getRuntime().availableProcessors();
                        //执行线程池
                        ExecutorService fixedPool = Executors.newFixedThreadPool(processors * 2);
                        //处理所有客户机连接
                        while (true){
                            //accept()如果无连接，则阻塞，否则接受连接并创建新的会话套接字
                            Socket fileSocket = listenerSocket.accept();
                            //文件接收线程为SwingWorker类型的后台工作线程
                            SwingWorker<Integer, Object> receive = new ReceiveFile(fileSocket,   ServerView.this);
                            //用线程池调度客户线程运行
                            fixedPool.execute(receive);
                        }

                    }catch (Exception e){
                        JOptionPane.showMessageDialog(null, e.getMessage(), "错误提示", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }).start();

        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "错误提示", JOptionPane.ERROR_MESSAGE);
        }

        jbStart.setEnabled(false);
    }

    private void formWindowClosed(java.awt.event.WindowEvent evt) {
        // TODO add your handling code here:
        if (clientSocket != null) {
            try {
                clientSocket.close();
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException ex) {
            }
        }

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                try {
                    UIManager.setLookAndFeel(info.getClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
                    e.printStackTrace();
                }
                break;
            }
        }

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new ServerView().setVisible(true);
            }
        });

    }

    // Variables declaration - do not modify
    private JLabel jLabel1;
    private JLabel jLabel2;
    private JPanel jPanel1;
    private JPanel jPanel2;
    private JScrollPane jScrollPane1;
    private JScrollPane jScrollPane4;
    private JScrollPane jScrollPane5;
    private JTable jTable1;
    private JTextArea jTextArea2;
    private JButton jbStart;
    private JPanel jp_bottom;
    private JPanel jp_top;
    private JTextArea jtaMessage;
    private JTextField jtfIpaddress;
    private JTextField jtfPort;
    private DefaultTableModel tableModel;
    // End of variables declaration

    public void consoleJTA(String text){
        jtaMessage.append(text);
    }

    public void onlineListJTA(String text){
        jTextArea2.append(text);
    }

    public void offlineListJTA(String text){
        jTextArea2.getText().replaceAll(text,"");
    }

    public void updateTable(String[] user){
        int row = tableModel.getRowCount() + 1;
        user[0] = String.valueOf(row);
        tableModel.addRow(user);
        FitTableColumns(jTable1);
    }

    //使JTable列宽适应文本内容
    private void FitTableColumns(JTable myTable){
        JTableHeader header = myTable.getTableHeader();
        int rowCount = myTable.getRowCount();

        Enumeration<TableColumn> columns = myTable.getColumnModel().getColumns();
        while(columns.hasMoreElements()){
            TableColumn column = columns.nextElement();
            int col = header.getColumnModel().getColumnIndex(column.getIdentifier());
            int width = (int)myTable.getTableHeader().getDefaultRenderer()
                    .getTableCellRendererComponent(myTable, column.getIdentifier()
                            , false, false, -1, col).getPreferredSize().getWidth();
            for(int row = 0; row<rowCount; row++){
                int preferredWidth = (int)myTable.getCellRenderer(row, col).getTableCellRendererComponent(myTable,
                        myTable.getValueAt(row, col), false, false, row, col).getPreferredSize().getWidth();
                width = Math.max(width, preferredWidth);
            }
            header.setResizingColumn(column); // 此行很重要
            column.setWidth(width+myTable.getIntercellSpacing().width);
        }
    }

}
